package com.fauks.ssm.springdata.jpa.repository;

import com.fauks.ssm.entity.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

/**
 * 1.JpaRepository：封装基本的CRUD
 * 2.JpaSpecificationExecutor：封装复杂查询
 */
public interface CustomerRepository extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {

    /**
     * jpql基本查询
     * 默认参数需要和占位符顺序保持一致
     * 需要先传入custName再传入id
     */
    @Query(value = "from Customer where custName =? and custId=?")
    Customer findByNameAndId(String custName, Long custId);

    /**
     * 可以使用?索引的方法指定参数位置
     */
    @Query(value = "from Customer where custId =?2 and custName=?1")
    Customer findByNameAndId2(String custName, Long custId);

    /**
     * 根据Id更新客户名称
     * <p>
     * 1. @Query表示查询用于配置jpql语句
     * 2. 使用@Modifying声明为更新操作
     * 3. jpql完成更新、删除操作，需要事务支持，结束后默认回滚事务，看似执行成功但是数据库没有更新，
     * 此时还需要使@Rollback设置不自动回滚
     */
    @Query("update Customer set custName=? where custId=?")
    @Modifying
    void updateCustomerById(String custName, Long custId);

    /**
     * 使用sql查询
     * nativeQuery:表示使用原生sql查询
     */
    @Query(value = "select * from cst_customer where cust_name like ?", nativeQuery = true)
    List<Object[]> queryBySql(String name);

    /**
     * 命名查询
     * 对jpal更加深入的封装，按照SpringDataJpa提供的方法名称规则定义方法，不需要配置jpql语句
     * findBy查询
     * 对象属性名首字母大写：查询条件 例如findByCustName 按照名称查询
     */
    Customer findByCustName(String name);

    /**
     * 模糊匹配
     * findBy+属性名称+查询方式(like、isnull) findByCustNameLike
     */
    List<Customer> findByCustNameLike(String name);

    /**
     * 多条件查询
     * findBy+属性名称+查询方式+多条件连接符(and、or)+其他属性名+查询方式
     */
    Customer findByCustNameLikeAndCustLevel(String name, String level);
}
